/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef EL_PROTOCOL_SERIAL_COMMAND_HANDLER_H
#define EL_PROTOCOL_SERIAL_COMMAND_HANDLER_H

#include <string>
#include <unordered_map>
#include <nlohmann/json.hpp>
#include <mutex>
#include "command_handler_base.h"

namespace El {
namespace Protocol {

// 串口配置信息结构
struct SerialConfig {
    std::string port;           // 串口端口号
    uint32_t baud_rate;         // 波特率
    uint8_t data_bits;          // 数据位
    uint8_t stop_bits;          // 停止位 
    std::string parity;         // 校验位：none/odd/even/mark/space
    bool enabled;               // 是否启用串口
};

// 串口发送结果结构
struct SerialSendResult {
    std::string status;         // 发送状态：sent/error
    uint32_t bytes_sent;        // 已发送字节数
    std::string response_data;  // 响应数据（Base64编码）
    uint32_t response_bytes;    // 响应数据字节数
    std::string timestamp;      // 发送时间戳
    std::string response_timestamp; // 响应时间戳
};

/**
 * @brief 串口命令处理器
 * 负责处理串口相关的所有命令，包括获取和设置串口配置、发送串口数据等
 */
class SerialCommandHandler : public CommandHandlerBase {
public:
    /**
     * 注册串口命令处理函数到处理器映射表
     * 
     * @param handlers 命令处理函数映射表，键为命令名称，值为处理函数
     */
    void RegisterMethodHandlers(
        std::unordered_map<std::string, std::function<nlohmann::json(const std::string &, const nlohmann::json &)>>
            &handlers);

private:
    /**
     * @brief 处理获取串口配置请求
     * @param id 请求ID
     * @param params 请求参数，包含串口端口号
     * @return 包含串口配置信息的响应JSON
     */
    nlohmann::json HandleSerialGetConfig(const std::string &id, const nlohmann::json &params);

    /**
     * @brief 处理设置串口配置请求
     * @param id 请求ID
     * @param params 请求参数，包含要设置的串口配置
     * @return 包含设置结果的响应JSON
     */
    nlohmann::json HandleSerialSetConfig(const std::string &id, const nlohmann::json &params);

    /**
     * @brief 处理发送串口数据请求
     * @param id 请求ID
     * @param params 请求参数，包含端口号、数据和编码方式
     * @return 包含发送结果的响应JSON
     */
    nlohmann::json HandleSerialSend(const std::string &id, const nlohmann::json &params);

    /**
     * @brief 验证串口端口号是否有效
     * @param port 串口端口号
     * @return true 有效，false 无效
     */
    bool ValidateSerialPort(const std::string &port);

    /**
     * @brief 验证波特率是否有效
     * @param baud_rate 波特率
     * @return true 有效，false 无效
     */
    bool ValidateBaudRate(uint32_t baud_rate);

    /**
     * @brief 验证串口参数是否有效
     * @param data_bits 数据位
     * @param stop_bits 停止位
     * @param parity 校验位
     * @return true 有效，false 无效
     */
    bool ValidateSerialParams(uint8_t data_bits, uint8_t stop_bits, const std::string &parity);

    /**
     * @brief 将字符串校验位转换为枚举值
     * @param parity 字符串校验位
     * @return 校验位枚举值
     */
    uint8_t ConvertParityFromString(const std::string &parity);

    /**
     * @brief 将校验位枚举值转换为字符串
     * @param parity 校验位枚举值
     * @return 字符串校验位
     */
    std::string ConvertParityToString(uint8_t parity);

    /**
     * @brief 解码数据（支持base64、hex、ascii）
     * @param data 编码后的数据
     * @param encoding 编码方式
     * @return 解码后的数据
     */
    std::vector<uint8_t> DecodeData(const std::string &data, const std::string &encoding);

    /**
     * @brief 编码数据为Base64
     * @param data 原始数据
     * @return Base64编码后的字符串
     */
    std::string EncodeToBase64(const std::vector<uint8_t> &data);

private:
    mutable std::mutex serialMutex_; // 串口操作互斥锁
};

} // namespace Protocol
} // namespace El

#endif // EL_PROTOCOL_SERIAL_COMMAND_HANDLER_H
